package com.javaxiaobear.base.framework.security;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.asymmetric.Sign;
import cn.hutool.jwt.signers.JWTSigner;
import java.nio.charset.Charset;

public class AsymmetricJWTSigner implements JWTSigner {
  private Charset charset = CharsetUtil.CHARSET_UTF_8;
  private final Sign sign;

  /**
   * 构造
   *
   * @param algorithm 算法字符串表示
   */
  public AsymmetricJWTSigner(String algorithm, RSA rsa) {
    this.sign = new Sign(algorithm, rsa.getPrivateKey(), rsa.getPublicKey());
  }

  /**
   * 设置编码
   *
   * @param charset 编码
   * @return 编码
   */
  public AsymmetricJWTSigner setCharset(Charset charset) {
    this.charset = charset;
    return this;
  }

  @Override
  public String sign(String headerBase64, String payloadBase64) {
    final String dataStr = StrUtil.format("{}.{}", headerBase64, payloadBase64);
    return Base64.encodeUrlSafe(sign(StrUtil.bytes(dataStr, charset)));
  }

  /**
   * 签名字符串数据
   *
   * @param data 数据
   * @return 签名
   */
  protected byte[] sign(byte[] data) {
    return sign.sign(data);
  }

  @Override
  public boolean verify(String headerBase64, String payloadBase64, String signBase64) {
    return verify(
        StrUtil.bytes(StrUtil.format("{}.{}", headerBase64, payloadBase64), charset),
        Base64.decode(signBase64));
  }

  /**
   * 验签数据
   *
   * @param data 数据
   * @param signed 签名
   * @return 是否通过
   */
  protected boolean verify(byte[] data, byte[] signed) {
    return sign.verify(data, signed);
  }

  @Override
  public String getAlgorithm() {
    return this.sign.getSignature().getAlgorithm();
  }
}
